package com.jediflasher.game_server.services

import java.io.DataOutputStream
import com.jediflasher.game_server.messages.RequestCharacterInfo.CharacterInfoResponse.Builder
import com.jediflasher.game_server.messages.RequestWorldInfo.{WorldInfoResponse, WorldInfoRequest}
import com.jediflasher.game_server.core.events.Event
import com.jediflasher.game_server.messages.MessageWrapper
import com.jediflasher.game_server.messages.ServiceMethodMovement.MethodMovement
import com.jediflasher.game_server.messages.HeaderMessage.{ServiceType, MessageType}
import com.jediflasher.game_server.messages.RequestCharacterMove.CharacterMoveRequest
import com.jediflasher.game_server.messages.MessageChangeUsers.ChangeUsers
import com.jediflasher.game_server.messages.RequestCharacterInfo.{CharacterInfoRequest, CharacterInfoResponse}
import com.jediflasher.game_server.data.{SuperUserData, UserData, WorldData}
import com.jediflasher.game_server.events.data.world.{WorldActorDataEvent, WorldActorDataEventType, WorldDataEventType}
import com.jediflasher.game_server.util.log.Logger

/**
 * User: Obi
 * Date: 05.08.11
 * Time: 18:18
 */

class ServiceMovement(out: DataOutputStream, worldData: WorldData, superUser:SuperUserData) extends AbstractService(out, worldData, superUser) {

	init();

	def init() {
		worldData.addListener(WorldDataEventType.USER_ADDED, userAddedHandler);
		Logger.log("USER_ADDED Listener created");
	}

	def process(messageWrapper: MessageWrapper) {
		messageWrapper.message match {
			case m:CharacterMoveRequest => processMove(messageWrapper);
			case m:WorldInfoRequest => processWorldInfo(messageWrapper);
			case m:CharacterInfoRequest => processCharInfo(messageWrapper);
		}
	}

	def processMove(messageWrapper: MessageWrapper) {
		val message: CharacterMoveRequest = messageWrapper.message.asInstanceOf[CharacterMoveRequest];

		val xPos = message.getXPos;
		val yPos = message.getYPos;

		val user:UserData = worldData.getUser(superUserId);
		user.setPosition(xPos, yPos);
	}

	def processWorldInfo(messageWrapper: MessageWrapper) {
		val users = this.worldData.getUsers;
		val message = WorldInfoResponse.newBuilder();
		users.foreach(u => message.addUsers(u.id));
		send(message.build(), MessageType.RESPONSE, MethodMovement.WORLD_INFO_VALUE, messageWrapper.requestId);
	}

	def processCharInfo(messageWrapper: MessageWrapper) {
		val message: CharacterInfoRequest = messageWrapper.message.asInstanceOf[CharacterInfoRequest];

		val id = message.getCharacterId;
		val userData:UserData = worldData.getUser(id);

		val response: Builder = CharacterInfoResponse.newBuilder();
		response.setXPos(userData.x).setYPos(userData.y).setCharacterId(userData.id).setName(userData.name);

		send(response.build(), MessageType.RESPONSE, MethodMovement.CHARACTER_INFO_VALUE, messageWrapper.requestId);
	}

	def userAddedHandler(event: Event) {
		val user: UserData = event.getData.asInstanceOf[UserData];
		Logger.log("Position changed listener created");
		// если мы добавлены в мир, значит только что залогинились и нужна инфа
		if (user.id == superUserId) {
			val message = ChangeUsers.newBuilder();
			
			val it = worldData.getUsers;
			while(it.hasNext) {
				val u = it.next();
				u.addListener(WorldActorDataEventType.POSITION_CHANGE, positionChangeHandler);
				message.addUsers(u.id);
			}

			send(message.build(), MessageType.RESPONSE, MethodMovement.USERS_ADD_VALUE);
		}
		// если просто какой-то хуй добавился
		else {
			user.addListener(WorldActorDataEventType.POSITION_CHANGE, positionChangeHandler);
			val message = ChangeUsers.newBuilder();
			message.addUsers(user.id);
			send(message.build(), MessageType.RESPONSE, MethodMovement.USERS_ADD_VALUE);
		}
	}

	def positionChangeHandler(event:Event) {
		val user:UserData = event.target.asInstanceOf[UserData];
		val moveResponse: Builder = CharacterInfoResponse.newBuilder();
		moveResponse.setXPos(user.x).setYPos(user.y).setCharacterId(user.id);

		send(moveResponse.build(), MessageType.RESPONSE, MethodMovement.CHARACTER_INFO_VALUE);
	}

	override def getServiceType: ServiceType = ServiceType.MOVEMENT;
}